BUILD-RESULT — native rdmodelrouter gateway v0.4.0
2026-09-27 18:04:53 EDT → 2026-09-27 18:36:14 EDT · rdmsm4x. Builder codex@rdmsm4x/rmrgateway0927; lead rdmodelrouter@rdmsm4x/rmr0926. TASK-20260927-66, parent FEAT-20260926-11. Rich decision DEC-20260927-12, recorded as DEC-RMR-42–45. Prototype. Commit-only; no merge or push. Worktree /Users/richh/dev/_worktrees/rdmodelrouter-gateway-20260927. Run folder /Users/richh/dev/_handoff/rdmodelrouter-gateway-20260927.
Delivered
- Native Swift
rdmodelrouterd, HTTP/1.1 on localhost/fleet interfaces, default port 12434. OpenAI-compatible text chat, incremental SSE, live model discovery, supported embeddings, read-only route/explain and own-caller usage. - Authenticated requests only. Namespaced explicit models or auto with v3 feature classification, catalog fit/quality/speed estimates, live health, capability, privacy and caller budget. Rationale response header and nonstream JSON field.
- Enabled local/fleet Ollama, local ToshLLM, AINetNode, OpenRouter and xAI adapters; compatible ToshLLM cloud adapter with an honestly unconfigured endpoint. Owned SSH loopback forwards, startup readiness checks, clean signal shutdown.
- XEntropy inference broker first, API-key kinds only, matching provider and expiry validation; own-provider Keychain fallback (native read then bounded pipe-only system security helper). No subscription OAuth inference, login refresh, browser cookies, token arguments or native subscription auth-file reads in the gateway. Existing subscription task launch behavior remains separate.
keys issue <caller>stores a new 256-bit random key in Keychain, never prints it. Owner-only atomic/flock ledger stores digests and caller counters. Duplicate issuance refuses replacement. Explicit foreground terminal/app disclosure.- Lifetime USD budgets set by Rich in app or CLI. New keys have $0 paid budget; free/local calls unlimited. Atomic pessimistic reservations before inference, provider-cost settlement, persistent holds for unknown cost/failure/crash. Tools, images and premium tiers are excluded from this paid text contract.
- CLI complete/serve/models/mcp/gateway status/keys issue/budget/reveal. MCP stdio route, explain, complete, models, usage; authenticated through the same daemon.
- Native Gateway tab: endpoint, health, caller issuance/reveal, request/token counts, spend/holds and explicit budget controls. Two real app screenshots.
- LaunchAgent installer, enabled by default, RunAtLoad/KeepAlive. Production installer signs/notarizes first; full app installer includes gateway installation. Separate --prepare and --development QA modes. Prior artifacts are archived.
- README, INTERFACES, AGENTS decision correction, docs/GATEWAY.md with xattr inbound/outbound and bulk-local integration plus Tyrell guide. No Tyrell edits.
Base correction
Assigned worktree and main were both at collectors a32a5df, not after routing integration. With a clean worktree, advanced only gateway branch by rebasing to routing branch 882f619, including its two verifier fixes. Main was untouched. No merge/push. Gateway commit is a descendant of those routing commits.
Verification evidence
| Check | Result | Run-folder evidence |
|---|---|---|
| Default full suite | 148 tests / 23 suites / 0 failures; rc 0 | tests-final.log |
| No ECSQuotaKit, isolated scratch | 148 / 23 / 0; rc 0 | tests-noquota-final.log |
| Universal release | CLI, daemon and app: x86_64 + arm64; Intel minos 26.7; valid plist | build-universal-final.log |
| QA signature | All three Developer ID, hardened runtime, trusted timestamp, verify strict | sign-qa.log |
| Fake HTTP backend | 401, models, chat, incremental SSE, embeddings, counters, no prompt/key in ledger | smoke-fake.json |
| Real local Ollama | 13 models; qwen3.5:4b-mlx chat + SSE; 2560-dimensional embedding | smoke-ollama.json |
| Caller counts | 3 requests, 0 failures, 28 input / 64 output tokens, zero spend/hold | smoke-ollama.json |
| Fleet/backend discovery | 506 models; details below | gateway-live-models.json, gateway-live-health.json |
| LaunchAgent | bootstrap rc 0, running PID, KeepAlive and RunAtLoad | launchagent-install-final.log, launchagent-running.txt |
| Local and LAN listener | 401 on 127.0.0.1, 192.168.0.29 and 10.0.4.26 | launchagent-http.json |
| Peer-to-hub listener | rdmbair13m5 → rdmsm4x tailnet endpoint returned 401 | peer-listener.txt |
| QA cleanup | bootout rc 0; subsequent service absent; plist archived; no owned forwards remain | launchagent-cleanup.json |
| Actual Gateway screenshots | captured and visually inspected; exact owned PIDs stopped | app-gateway.png, app-gateway-usage.png, capture*.json |
| No-secret scan | 66 in-memory known values, 173 files, 349 reachable blobs, current transcript; 0 findings; both controls passed | secret-scan-final.json |
| Artifact identity | SHA-256 and sizes for app/CLI/daemon/policy/screenshots | artifact-manifest.json |
| Whitespace/script syntax | git diff --check and zsh syntax checks rc 0 | rerunnable commands below |
Final script reruns update the precise SSE timing receipts. The first fake wire run delivered its first event at 0.006s and completed at 0.832s, proving streaming rather than whole-response buffering. Real Ollama delivered deltas and [DONE]. Tests use injected stores/transports or isolated temporary ledgers. No production caller store, real caller key issuance or paid inference was used for tests.
New gateway tests cover auth rejection, capabilities, streaming, explicit model errors, paid budget denial/settlement, retained unknown-cost reservations, parallel reservations and restart persistence, HTTP framing/smuggling, read-only explain, key generation/digest-only storage, duplicate issuance, broker OAuth/provider/ expiry rejection, matching Keychain fallback and MCP protocol/tools/errors. The old blanket no-listener source audit now permits only GatewayServer.swift; subscription endpoint/credential restrictions and UI no-routing checks remain.
Live backend results
- Ollama healthy on all six Macs: Studio 13; rdmbair13m5 9; rdmbair15m5 7; jdmbair13m5 2; rdmpw3265m 1; rdmpw3275m 1. Total 33 host/model entries.
- ToshLLM rdmpw3275m healthy: 15 model IDs through configured port 11435 using its own Keychain API credential. rdmpw3265m did not return a valid model list.
- OpenRouter: 458 live model entries and pricing metadata retrieved. No inference.
- xAI: own stored credential present, but both /v1/models and /v1/language-models returned HTTP 403. No credential rotation, account mutation or paid test.
- AINetNode Studio port 11435 unavailable/incompatible. No service started for it.
- ToshLLM cloud: no verified endpoint in fleet/catalog/localAI evidence or the official local-runtime project; adapter/configuration exists, URL remains unset.
Initial discovery raced SSH startup; readiness checks fixed it and the final full-fleet result is above. Initial unsigned QA listener worked on loopback but LAN timed out. Developer ID signing fixed LAN/peer reachability without changing the enabled firewall. Initial native Keychain read was unavailable for API items; the bounded trusted system-helper fallback restored OpenRouter/ToshLLM metadata.
Scope and remaining acceptance boundaries
- Paid calls: simulated with fake backends only. Real calls require Rich-set caller budgets and were not authorized as a spend test. xAI additionally needs working account/API access; observed 403 is retained as an external blocker.
- ToshLLM cloud: requires a real verified HTTPS endpoint and current tariffs. No fabricated endpoint or claim of live cloud inference.
- Release/install: worktree artifacts are Developer ID signed for QA, not notarized or installed as production. The QA LaunchAgent was stopped and its plist archived. Default-enabled production installation is implemented in the installer and belongs to the post-review lead workflow. Installed app untouched.
- UI controls: the actual Gateway views are captured; native CUA failed with "native pipe closed". Clicking real Reveal/Issue/Set budget is not claimed. Key lifecycle and budget behavior have injected-store tests; no screenshot contains a key. Usage screenshot displays actual isolated local-smoke counters.
- Budget meaning: an admission bound against known published prices, not an independent guarantee against provider tariff changes or misbilling. Unknown prices refuse spend. Unknown final cost retains a visible hold; no silent zero.
- Topology audit prescribed under Documents is absent (rc127); host and actual network/model probes supply current evidence. No account/session-store movement.
- No outbound messages, paid inference, credential rotation, model download, user-data deletion, main merge, push, Tyrell/shared-library edit or app install.
Reproduce
From the assigned worktree:
nice -n 10 ~/bin/build_slot.zsh wrap --worktree "$PWD" swift test --jobs 2
RMR_DISABLE_QUOTA_KIT=1 nice -n 10 ~/bin/build_slot.zsh wrap --worktree "$PWD" swift test --scratch-path .build/noquota --jobs 2
scripts/build-status-app.zsh
python3 scripts/gateway-smoke.py --binary .build/status-app/rdmodelrouterd --policy "$PWD/policy/policy.v3.json" --output /tmp/rmr-gateway-check
python3 scripts/gateway-smoke.py --binary .build/status-app/rdmodelrouterd --policy "$PWD/policy/policy.v3.json" --output /tmp/rmr-gateway-check --ollama
zsh -n scripts/install-gateway.zsh scripts/install-local.zsh
git diff --checkApple Notes PENDING: this execution session is Background. fleet-notes-publish requires a file copy rather than a GUI workaround. Changelog copies are retained under both ~/dev/LLM/Claude/changelogs and ~/dev/LLM/Codex/changelogs. Resume: review this branch and evidence, then lead owns integration and the signed, notarized default-enabled installation. Undo source with a new revert commit; QA artifacts and isolated ledgers are preserved, not deleted.
Final commit receipt — 2026-09-27 18:40:17 EDT · rdmsm4x
Commit b3187b69faef40783a0e267bf4a771e35df269ae on
rmr/gateway-20260927. 26 explicit paths committed; Agent
trailer present; worktree clean. No merge/push. Predecessor BUILD-RESULT
preserved under archive/gateway-predecessor-20260927. Postcommit scan:
66 known in-memory values, 179 files, 374 reachable blobs and current
transcript; zero findings, exact-match/pattern controls passed. Notes
helper rc3 (Background); both changelog copies retained. QA LaunchAgent
absence confirmed after asynchronous bootout; its plist archived. No
owned port12434 listener or SSH forwards remain. Signing is QA only, no
notarization/install.